package com.autonavi.collapse.config;

import com.autonavi.collapse.task.model.ConfigValue;
import com.autonavi.collapse.task.model.ExtendedMap;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class XmlConfigLoader implements ConfigLoader {


    @Override
    public List<ExtendedMap> load(File file) throws Exception {
        List<ExtendedMap> result = new ArrayList<>();
        Document document = Jsoup.parse(file, StandardCharsets.UTF_8.name());
        Elements configElements = document.select("config");
        for (Element configElement : configElements) {
            Map<String, ConfigValue> configMap = new HashMap<>();
            String name = configElement.attr("name");
            List<String> keys = new ArrayList<>();
            for (Element child : configElement.children()) {
                parseValue(child, keys, configMap);
            }
            result.add(new ExtendedMap(name, configMap));
        }
        return result;
    }

    public void parseValue(Element element, List<String> keys, Map<String, ConfigValue> result) throws ClassNotFoundException {
        if (element == null) {
            return;
        }
        List<String> myKeys = new ArrayList<>();
        myKeys.add(element.tagName());
        Elements children = element.children();
        if (children.isEmpty()) {
            String type = element.attr("class");
            String text = element.text();
            String key = StringUtils.join(myKeys, ",");
            if (StringUtils.isBlank(type)) {
                result.put(key, new ConfigValue(text));
            } else {
                result.put(key, new ConfigValue(text, Class.forName(type)));
            }
        } else {
            for (Element child : children) {
                parseValue(child, myKeys, result);
            }
        }
    }
}
